//
// Created by huangjunhao on 2022/9/12.
//

//#include "SeqList.h"
#include <corecrt.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
// 为了应付作业，课后改回来

typedef  int SLDataType;
//不想用静态
//#define N 10
typedef struct SeqList{
    SLDataType* a;  //指向动态开辟的数组
    size_t size;        //有效数据个数
    size_t capacity;    //容量大小
}SL,SeqList;

void menu();
void checkcapacity(SeqList* ps);
void slCreate(SeqList* ps);
void slOutPrint(SeqList* ps);
void SLInsert(SL* ps,int pos,SLDataType x);
void SLErase(SL* ps,int pos);

int main() {
    printf("Hello, World!\n 开始了解顺序表！\n");
    SeqList s;
    int cord,index,value;
    do {
        menu();
        printf("请输入您的选择（1，2，3，4）\n");
        scanf("%d",&cord);

        switch (cord) {
            case 1:
                slCreate(&s);
                slOutPrint(&s);
                break;
            case 2:
                printf("\n 请输入插入的位置 i , 插入值1x: （中间用逗号隔开）：");
                scanf("%d,%d",&index,&value);
                SLInsert(&s,index,value);
                slOutPrint(&s);
                break;
            case 3:
                printf("\n 请输入删除的位置 i :");
                scanf("%d",&index);
                SLErase(&s,index);
                slOutPrint(&s);
                break;
            case 4:
                exit(0);
        }

    } while (cord<=4);
    return 0;
}



void menu() {
    printf("\n\t 主菜单 \t\n");
    printf("\t 1    建立线性表 \t\n");
    printf("\t 2    插入一个元素 \t\n");
    printf("\t 3    删除一个元素 \t\n");
    printf("\t 4    结束程序 \t\n");
}

void slOutPrint(SeqList* ps){
    system("cls");
    //断言防止错误
    assert(ps);
    for(int i=0;i< ps->size;++i){
        printf("%d", ps->a[i]);
    }
}
void slInit(SeqList* ps){
    //malloc 分配内存  sizeof 返回变量或类型大小
    ps->a = malloc(sizeof(SLDataType)*4);
    if(ps->a == NULL){
        printf("申请内存失败\n");
        exit(-1);
    }
    ps->size = 0;
    ps->capacity = 4;
}

//简单的添加数组元素
void slCreate(SeqList* ps){
    //初始化
    slInit(ps);
    printf("\n 请输入表长n=");
    scanf("%zd",&ps->size);
    assert(ps);
    checkcapacity(ps);
    printf(" 请输入表数据：\n");
    for (int i = 0; i < ps->size; i++) {
        printf("\n data=");
        scanf("%d",&ps->a[i]);
    }
}

void slDestory(SL* ps){
    free(ps->a); //空间释放
    ps->a = NULL; //指针设置为空 防止野指针
    ps->size = ps->capacity =0;
}

//检查空间，如果满了，进行扩容
void checkcapacity(SeqList* ps){
    //如果满了需要扩容(如果原地有足够空间直接原地扩容，没有则另找一个新空间，把数组拷过去再释放掉旧的空间)
    if(ps->size >= ps->capacity){
        //通常增2倍
        ps->capacity *=2;
        ps->a = (SLDataType*)realloc(ps->a, sizeof(SLDataType)*ps->capacity);
        if(ps->a == NULL){
            printf("扩容失败\n");
            exit(-1);
        }
    }
}


void SLInsert(SL* ps,int pos,SLDataType x){
    assert(ps);
    assert(pos < ps->size && pos >=0); //断言为真就没事
    checkcapacity(ps);
    int end = ps->size-1;
    while(end >= pos){
        ps->a[end+1] = ps->a[end];
        --end;
    }
    ps->a[pos] = x;
    ps->size++;
}
void SLErase(SL* ps,int pos){
    assert(ps);
    assert(pos <= ps->size && pos >=0);

    int start= pos;
    while(start< ps->size-1){
        ps->a[start] = ps ->a[start+1];
        ++start;
    }
    ps->size--;

}
